package com.winchain.provider.expiration.cmd;

import com.shell.feign.PubMessageFeign;
import com.shell.framework.command.CommandContext;
import com.shell.framework.command.ICommand;
import com.shell.framework.utils.CommonDataUtil;
import com.shell.framework.utils.MessageSender;
import com.shell.governor.modules.message.keyword.SysSndTimeoutKeyword;
import com.winchain.chainbill.basic.cus.service.CusRecService;
import com.winchain.chainbill.bill.base.po.CbRec;
import com.winchain.chainbill.bill.base.po.CbSnd;
import com.winchain.chainbill.bill.base.service.CbRecService;
import com.winchain.chainbill.bill.base.service.CbSndService;
import com.winchain.provider.expiration.po.CbCredit;
import com.winchain.provider.expiration.po.CbDebit;
import com.winchain.provider.expiration.rx.BillExpirationEvent;
import com.winchain.provider.expiration.service.BillExpQueryService;
import com.winchain.provider.expiration.service.BillExpStateService;
import com.winchain.provider.expiration.service.CbCreditService;
import com.winchain.provider.expiration.service.CbDebitDtlService;
import com.winchain.provider.expiration.service.CbDebitService;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class BillExpSndSettlCmd implements ICommand<BillExpirationEvent> {
	@Autowired
	private CbRecService cbRecService;
	@Autowired
	private BillExpQueryService billExpQueryService;
	@Autowired
	private BillExpStateService billExpStateService;
	@Autowired
	private CbDebitService cbDebitService;
	@Autowired
	private CbCreditService cbCreditService;
	@Autowired
	private CbDebitDtlService cbDebitDtlService;
	@Autowired
	PubMessageFeign pubMessageFeign;
	@Autowired
	CusRecService basCusService;
	@Autowired
	CbSndService cbSndService;

	public boolean execute(CommandContext<BillExpirationEvent> context) throws Exception {
		BillExpirationEvent event = (BillExpirationEvent) context.getSource();
		String expDate = event.getDate();
		boolean pm = event.isPm();
		String grpId = event.getGrpId();

		sendProcess(expDate, pm, grpId);

		return false;
	}

	private void sendProcess(String expDate, boolean pm, String grpId) throws Exception {
		List<CbRec> bills = this.billExpQueryService.selectExpSndBills(expDate, pm, grpId);
		CbDebit debit = null;
		String billState = "";
		for (CbRec bill : bills) {
			if (this.billExpStateService.rollback(bill, pm)) {
				bill = this.cbRecService.selectByKeyWithNewTx(bill.getBillId());
			}
			billState = bill.getBillState();

			debit = this.cbDebitService.saveBillDebit(bill, expDate, false);
			if (("S005".equals(billState)) || ("S012".equals(billState)) || ("S011".equals(billState))
					|| ("S035".equals(billState))) {
				if (bill.getExpDate().equals(expDate)) {
					this.cbCreditService.saveBillCredit(debit, bill, expDate);

					this.billExpStateService.expire(bill);
				}
			} else {
				Collection<CbRec> children = this.billExpQueryService.getExpChdBills(expDate, bill.getBillId());
				List<CbCredit> credits;
				CbCredit credit;
				if ((children != null) && (children.size() > 0)) {
					credits = new ArrayList();
					credit = null;
					for (CbRec child : children) {
						if (this.billExpStateService.rollback(child, pm)) {
							child = this.cbRecService.selectByKeyWithNewTx(child.getBillId());
						}
						credit = this.cbCreditService.saveBillCredit(debit, child, expDate);
						if (credit != null) {
							credits.add(credit);
						}
						this.billExpStateService.expire(child);
					}
				}
				if (bill.getExpDate().equals(expDate)) {
					this.billExpStateService.expire(bill);
				}
			}
			if (debit != null) {
				this.cbDebitDtlService.saveCbDebitDtl(debit, bill);
			}
		}
	}

	public static BigDecimal getAmount(List<CbCredit> credits) {
		BigDecimal allAmount = new BigDecimal(0);
		BigDecimal actualAmount = null;
		for (CbCredit cr : credits) {
			actualAmount = cr.getBillAmount();
			allAmount = allAmount.add(actualAmount);
		}
		return allAmount;
	}

	public void sendMessage(CbRec bill) throws Exception {
		CbSnd cbSnd = new CbSnd();
		cbSnd.setBillId(bill.getBillId());
		CbSnd data = (CbSnd) this.cbSndService.selectOne(cbSnd);

		String template = "MT01204";
		SysSndTimeoutKeyword keyWord = new SysSndTimeoutKeyword();
		keyWord.setBillAmt(String.valueOf(bill.getBillAmt()));
		keyWord.setSellerNm(data.getSellerNm());
		keyWord.setSndDate(data.getCreateTime());

		String senderId = CommonDataUtil.getUserId();

		String buyerId = data.getBuyerId();
		MessageSender.sendMessageByTmpl(senderId, template, keyWord, buyerId);
	}
}
